/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pki;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

/**
 *
 * @author Gaetan
 */
public class KeyStoreTools {

    private KeyStore keyStore;
    
    public KeyStoreTools(String type, String password) {
        try {
            keyStore = KeyStore.getInstance(type);
            keyStore.load(null, password.toCharArray());
        } catch (Exception ex) {
        }
    }

    public KeyStoreTools(String type, String fileName, String password) {
        try {
            keyStore = KeyStore.getInstance(type);
            InputStream in = new BufferedInputStream(new FileInputStream(new File(PKIService.keyStorePath+fileName+".ks")));
            keyStore.load(in, password.toCharArray());
        } catch (Exception ex) {
}
    }
    
    public KeyStore getKeyStore() {
        return keyStore;
    }

    public static boolean isKeyStoreExist(String name) {
        return new File(PKIService.keyStorePath+name+".ks").exists();
    }
    
    public boolean saveKeyStore(String fileName, String password) {
        OutputStream out = null;
        try {
            out = new BufferedOutputStream(new FileOutputStream(new File(PKIService.keyStorePath+fileName+".ks")));
            keyStore.store(out, password.toCharArray());
            out.close();
        } catch (Exception ex) {
            return false;
        }
        return true;
    }

    public boolean addCertificate(String alias, Certificate cert) {
        try {
            keyStore.setCertificateEntry(alias, cert);
        } catch (KeyStoreException ex) {
            ex.printStackTrace();
            return false;
        }
        return true;
    }

    public X509Certificate getCertificate(String alias) {
        Certificate cert = null;
        try {
            cert = keyStore.getCertificate(alias);
        } catch (KeyStoreException ex) {
        }
        return (X509Certificate) cert;
    }

    public boolean addPrivateKey(String alias, PrivateKey privateKey, String password, Certificate[] chain) {
        try {
            System.out.println(privateKey.getAlgorithm());
            KeyStore.PrivateKeyEntry pke = new KeyStore.PrivateKeyEntry(privateKey, chain);
            keyStore.setEntry(alias, pke, new KeyStore.PasswordProtection(password.toCharArray()));
        } catch (KeyStoreException ex) {
            ex.printStackTrace();
            return false;
        }
        return true;
    }

    public PrivateKey getPrivateKey(String alias, String password) {
        PrivateKey pk = null;
        try {
            pk = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
        } catch (Exception ex) {
        }
        return pk;
    }

    public ArrayList<Certificate> getCertificateChaine(String alias) {
        Certificate[] certChain = null;
        try {
            certChain = keyStore.getCertificateChain(alias);
        } catch (KeyStoreException ex) {
        }
        return new ArrayList<>(Arrays.asList(certChain));
    }
    
    private ArrayList<String> getAllAliases() {
        ArrayList<String> arrAlias = new ArrayList<>();
        Enumeration<String> enumAlias = null;
        try {
            enumAlias = keyStore.aliases();
            while (enumAlias.hasMoreElements()) {
                String s = enumAlias.nextElement();
                arrAlias.add(s);
            }
        } catch (KeyStoreException ex) {
        }
        return arrAlias;
    }
    
    public boolean aliasExists(String alias){
        ArrayList<String> arrAlias = getAllAliases();
        for(String a : arrAlias){
            if(a.equals(alias)) return true;
        }
        
        return false;
    }

    public ArrayList<X509Certificate> getAllCertificates() {
        ArrayList<X509Certificate> arrCertificates = new ArrayList<>();
        Enumeration<String> aliases;
        try {
            aliases = keyStore.aliases();
            while (aliases.hasMoreElements()) {
                String alias = aliases.nextElement();
                X509Certificate x = getCertificate(alias);
                if (x!=null) {
                    arrCertificates.add(x);
                }
            }
        } catch (KeyStoreException ex) {
            ex.printStackTrace();
        }
        return arrCertificates;
    }
 
    public static PrivateKey getPrivateKeyTopLevel() {
        KeyStoreTools ksTopLevel = new KeyStoreTools("JCEKS", "top_level", "pkisecurity");
        PrivateKey privateKeyTopLevel = ksTopLevel.getPrivateKey("top_level", "pkisecurity");
        return privateKeyTopLevel;
    }
    
    public static X509Certificate getCertificateTopLevel() {
        KeyStoreTools ksTopLevel = new KeyStoreTools("JCEKS", "top_level", "pkisecurity");
        X509Certificate certifTopLevel = (X509Certificate) ksTopLevel.getCertificate("top_level");
        return certifTopLevel;
    }
}
